package com.example.demo.AppUtil;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.config.LocalDateTimeFormatConfig;
import com.example.demo.entity.AnToken;
import com.example.demo.service.IAnTokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/*
 * @Author:大力王
 * @Date:2024/6/19-19-23:57
 * 开始了
 */
@Slf4j
public class BaseActionUtil {
    /**
     * 得到request对象
     */
    @Autowired
    protected HttpServletRequest request;
    /**
     * 得到response对象
     */
    @Autowired
    protected HttpServletResponse response;
    /**
     * token
     */
    @Autowired
    protected IAnTokenService anTokenService;
    /**
     * 时间格式化
     */
    @Autowired
    private LocalDateTimeFormatConfig localDateTimeFormatConfig;
    /**
     * @param requestCode code
     * @param msg 消息
     * @param data 数据
     * @return Map<String, Object>
     * &#064;Description:构建统一格式返回对象
     * &#064;date  2016年9月2日
     * @author zhuliyun
     */
    public Map<String, Object> toResponsObject(int requestCode, String msg, Object data) {
        Map<String, Object> obj = new HashMap<String, Object>();
        obj.put("errno", requestCode);
        obj.put("errmsg", msg);
        if (data != null) {
            obj.put("data", data);
        }
        return obj;
    }
    /**
     * 将处理结果转换为成功的响应对象。
     * 此方法用于封装一个成功的响应消息体，其中包含状态码、消息和数据。
     * 状态码为0表示操作成功，消息文本为"执行成功"，数据部分则根据具体业务需求传递。
     * 日志记录了响应的具体内容，方便调试和跟踪。
     *
     * @param data 要返回给客户端的具体数据对象。
     * @return 包含成功标识、消息和数据的响应映射。
     */
    public Map<String, Object> toResponseSuccess(Object data) {
        // 封装成功响应对象
        Map<String, Object> rp = toResponsObject(0, "执行成功", data);
        // 记录响应内容到日志
        log.info("response:" + rp);
        // 返回响应对象
        return rp;
    }
    /**
     * 参数绑定异常
     */
    @ExceptionHandler({BindException.class, MissingServletRequestParameterException.class, UnauthorizedException.class, TypeMismatchException.class})
    @ResponseBody
    public Map<String, Object> bindException(Exception e) {
        if (e instanceof BindException) {
            return toResponsObject(1, "参数绑定异常", e.getMessage());
        } else if (e instanceof UnauthorizedException) {
            return toResponsObject(1, "无访问权限", e.getMessage());
        }
        return toResponsObject(1, "处理异常", e.getMessage());
    }
    public Map<String, Object> toResponseSuccess(String msg) {
        return toResponsObject(0, msg, "");
    }

    public Map<String, Object> toResponseSuccessForSelect(Object data) {
        Map<String, Object> result = new HashMap<>(2);
        result.put("list", data);
        return toResponsObject(0, "执行成功", result);
    }

    public Map<String, Object> toResponseFail(String msg) {
        return toResponsObject(1, msg, null);
    }

    /**
     * initBinder 初始化绑定 <br>
     * 这里处理了3种类型<br>
     * 1、字符串自动 trim 去掉前后空格 <br>
     * 2、java.util.Date 转换为 "yyyy-MM-dd HH:mm:ss" 格式<br>
     * 3、java.sql.Date 转换为 "yyyy-MM-dd" 格式<br>
     * 4、java.util.Timestamps 时间转换
     *
     * @param binder  WebDataBinder 要注册的binder
     * @param request 前端请求
     */
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {

        // 字符串自动Trim
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
    }

    /**
     * 获取请求方IP
     *
     * @return 客户端Ip
     */
    public String getClientIp() {
        String xff = request.getHeader("X-Real-IP");
        if (xff != null) {
            return xff;
        }
        xff = request.getHeader("x-forwarded-for");
        if (xff == null) {
            return "8.8.8.8";
        }
        return xff;
    }

    public JSONObject getJsonRequest() {
        JSONObject result = null;
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = request.getReader();) {
            char[] buff = new char[1024];
            int len;
            while ((len = reader.read(buff)) != -1) {
                sb.append(buff, 0, len);
            }
            result = JSONObject.parseObject(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 获取请求的用户Id
     *
     * @return 客户端Ip
     */
    public Long getUserId() {
        String token = request.getHeader(AuthorizationInterceptor.LOGIN_TOKEN_KEY);
        //查询token信息
        AnToken tokenEntity = anTokenService.queryByToken(token);
        LocalDateTime now = tokenEntity.getExpireTime();
        Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
        if (date.getTime() < System.currentTimeMillis()) {
            return null;
        }
        return tokenEntity.getUserId();
    }
}
